Ana içeriğe geç

Box ve DeReferansing

Pointlerlar içerisinde bir verinin adresini tutan veri yapısıdır. Bu adres bir veriyi işaret etmektedir. Aslında daha öncesinde çokça Rust içerisinde pointer yapılarını kullandık. En yaygın kullanılan pointer ise Referans (&) olmaktadır. Bu pointer yapılarının ekstra özellikleri bulunmamaktadır.

Bizlere normal referanslara göre ekstra özellik veren pointer'lar akıllı pointerlar (smart pointers) olmaktadır.

Smart Pointer yapıları C++ ile geliştirilmiştir ve Rust'a özgü bir konsept değildir.

Rust üzerinde popüler olan akıllı pointerlara bakılacak olunursa bunlardan ilki olan box heap üzerinde tutulmaktadır. Bir diğeri de RC olarak kısaltabileceğimiz Referance Count olmaktadır. Bu yapı birden fazla sahibe izin vermektedir.

Box Smart Pointer

İlk olarak Box Smart Pointer yapılarına bakacağız. Bu yapılar Rust'ın sunabileceği en düzgün Smart Pointer yapıları olmaktadır. Bu yapılar sayesinde Stack yerine Heap üzerinde veri kaydedebiliriz. Ancak bu veriyi heap üzerinde kaydetsek de pointer'ın kendisi Stack üzerinde kaydedilecektir.

Hadi bir tupple oluşturarak başlayalım! Bir box yapısı oluştururken box anahtar kelimesini kullanmaktayız. Sonrasında oluşturduğumuz bu box pointer değerini yazdırabiliriz.

fn main() {
let t = {12, "eggs"};
let b = box::new(t);

println!("{:?}", b)
}

Kodumuzu çalıştırdığımızda aslında beklendiği üzere tuple içerisindeki değerlerin yazdırıldığını görüntüleyebildik. Ancak burada dikkat edilmesi gereken neyin kaydedildiği değil nereye kaydedildiğidir. Aslında tupple'lar stack üzerinde tutulmaktadır. Ancak biz bu tupple değerini box methodu içerisine yerleştirdiğimizde tupple'ımız artık heap içerisinde varlığını göstermeye başlamıştır. Tupple'ımız konumunu heap içerisine alsa da b adı ile oluşturduğumuz ve bu tupple'ı işaret eden pointer stack içerisinde tutulmaya devam etmiştir.

### DeReferance

Pointerlar aynı zamanda içerilerinde dereferance yani referans kaldırıcı methodlar ile de gelmektedir. Bu durumu direkt olrak kod yapısında görüntüleyebiliriz.

let x = 5;
let y = &x;

Bir x değeri ve bu x değerinin referansına sahip bir y değeri oluşturduk

assert_eq!(5, x); // True
assert_eq!(5, y); // Error

Sonrasında bu değerleri kontrol etmek istediğimizde her ne kadar 5'in x'e eşit olduğunu görsek de y 5 değerinine değil de referansına sahip olduğu için Compiler bu kısımda karşılaştıramam hatası verdi. Bu durumu çözmek için referansı direkt veriye çeviren * yapısını kullanabiliriz.

assert_eq!(5, x); // True
assert_eq!(5, *y); // True

Artık y de 5 değerine sahip oldu ve kodumuz sıkıntısız çalıştı.

Bu işlemleri yukarıda ifade edildiği üzere normal referans ile yapmış olsak da bu işlemleri box referans ile de yapabiliriz.

let x = 5;
let y = Box::new(x);

assert_eq!(5, x); // True
assert_eq!(5, *y); // True